package com.entrogy.controller;

import com.entrogy.dao.SchoolMapper;
import com.entrogy.timing.TimingTaskService;
import com.entrogy.utils.RedissonManager;
import com.entrogy.utils.constants.Constants;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author xlr
 */
@Component
public class TimingTaskController{

	private static final Logger logger = LoggerFactory.getLogger(TimingTaskController.class);

	@Autowired
	private TimingTaskService uts;
	@Autowired
	private RedissonManager redissonManager;
	@Autowired
	private SchoolMapper schoolMapper;

	// 2、每天凌晨12:00更新
	@Scheduled(cron = "0 1 0 * * ?")
	private void createPassRecord() {
		RLock lock = redissonManager.getRedisson().getLock(Constants.PASSRECORD_TASK_LOCK);
		boolean getLock = false;
		try {
			//todo 若任务执行时间过短，则有可能在等锁的过程中2个服务任务都会获取到锁，这与实际需要的功能不一致，故需要将waitTime设置为0
			if (getLock = lock.tryLock(0, 5, TimeUnit.SECONDS)) {
				logger.info("创建通行记录表 来了  老弟~~~~~~");
				uts.createPassRecord();
			} else {
				logger.info("创建通行记录表的时候锁没有获取到锁");
			}
			Thread.sleep(5000);//睡一会儿在关闭锁
		} catch (InterruptedException e) {
			logger.error("创建通行记录表的时候获取锁异常",e);
		}finally {
			if (!getLock) {
				return;
			}
			lock.unlock();
			logger.info("创建通行记录表的时候释放锁");
		}
	}

	// 3、每天早上新建时间表2:10
	@Scheduled(cron = "0 10 2 * * ?")
	public void createDynArrangeAndPushTime() {
		RLock lock = redissonManager.getRedisson().getLock(Constants.CREATE_DYN_ARRANGE_AND_PUSH_TIME_TASK_LOCK);
		boolean getLock = false;
		try {
			if(getLock = lock.tryLock(0,5,TimeUnit.SECONDS)){//获取锁
				logger.info("创建动态时间规则表和推送时间功能 来了  老弟~~~~~~");
				uts.createTableAndPushTime();
			}else{
				logger.info("创建动态时间规则表和推送每个学校每个学生的通行时间的时候没有获取到锁");
			}
			Thread.sleep(5000);//睡一会儿在关闭锁
		} catch (InterruptedException e) {
			e.printStackTrace();
			logger.error("创建动态时间规则表和推送每个学校每个学生的通行时间的时候获取锁异常",e);
		} catch (ParseException e) {
			e.printStackTrace();
			logger.error("》》》》》注意呀》》》》》》创建动态时间规则表和推送每个学校每个学生的通行时间的时候报错=========================");
		}finally {
			if(!getLock){
				return;
			}
			lock.unlock();
			logger.info("创建动态时间规则表和推送每个学校每个学生的通行时间的时候释放锁");
		}
	}

	// 4、每隔1分钟时间，给请假的人设定时间（很少，不占啥资源），只管请假的，顺便把过期的假给消掉
	@Scheduled(cron = "0 */2 * * * ?")
	private void pushTimeInLeave() {
		RLock lock = redissonManager.getRedisson().getLock(Constants.PUSH_TIME_IN_LEAVE_TASK_LOCK);
		boolean getLock = false;
		try {
			if (getLock = lock.tryLock(0, 5, TimeUnit.SECONDS)) {
				uts.pushTimeInLeave();
			}
			Thread.sleep(5000);//睡一会儿在关闭锁
		} catch (InterruptedException e) {
			logger.error("每隔一分钟推送请假学生的时候获取锁异常",e);
		}finally {
			if (!getLock) {
				return;
			}
			lock.unlock();
		}
	}

	// 5、每天凌晨更新设备时间2:20
	@Scheduled(cron = "0 20 2 * * ?")
	private void setDeviceTime() {
		RLock lock = redissonManager.getRedisson().getLock(Constants.SET_DEVICE_TIME_TASK_LOCK);
		boolean getLock = false;
		try {
			if (getLock = lock.tryLock(0, 5, TimeUnit.SECONDS)) {
				logger.info("更新设备时间 来了  老弟~~~~~~");
				//查询所有学校的schoolCode
				List<Integer> schoolIds = schoolMapper.listSchoolCode();
				for (Integer schoolCode : schoolIds) {
					uts.setDeviceTime(schoolCode);
			}
			} else {
				logger.info("更新设备时间的时候锁没有获取到锁");
			}
			Thread.sleep(5000);//睡一会儿在关闭锁
		} catch (InterruptedException e) {
			logger.error("更新设备时间的时候获取锁异常",e);
		}finally {
			if (!getLock) {
				return;
			}
			lock.unlock();
			logger.info("更新设备时间的时候释放锁");
		}
	}

	//6.每天凌晨3点去判断支付过期人员，如果过期则设置 is_out_of_date = 0  1--没有过期 0--过期
	@Scheduled(cron = "0 0 3 * * ?")
	private void checkPayOrder(){
		RLock lock = redissonManager.getRedisson().getLock(Constants.PAY_ORDER_IS_OUT_OF);
		boolean getLock = false;
		try {
			if (getLock = lock.tryLock(0, 5, TimeUnit.SECONDS)) {
				logger.info("判断支付订单日期 来了  老弟~~~~~~");
				uts.checkPayOrder();
			} else {
				logger.info("判断支付订单日期的时候锁没有获取到锁");
			}
			Thread.sleep(5000);//睡一会儿在关闭锁
		} catch (InterruptedException e) {
			logger.error("判断支付订单日期的时候获取锁异常",e);
		}finally {
			if (!getLock) {
				return;
			}
			lock.unlock();
			logger.info("判断支付订单日期的时候释放锁");
		}
	}

	// TODO 上线后该为每隔10分钟
	// 每隔1分钟，将查询前12分钟的通行数据对应的我们系统的学生id并更新到通行记录表中
	@Scheduled(cron = "0 */2 * * * ?")
	private void updatePassRecordSystemId() {
		RLock lock = redissonManager.getRedisson().getLock(Constants.UPDATE_PASS_RECORD_SYSTEM_ID);
		boolean getLock = false;
		try {
			if (getLock = lock.tryLock(0, 5, TimeUnit.SECONDS)) {
				logger.info("正在将前12分钟的通行数据查询出学生id并更新到通行记录表中");
				uts.updatePassRecordSystemId();
			} else {
				logger.info("正在将前12分钟的通行数据查询出学生id并更新到通行记录表中的时候锁没有获取到锁");
			}
			Thread.sleep(5000);//睡一会儿在关闭锁
		} catch (InterruptedException e) {
			logger.error("正在将前12分钟的通行数据查询出学生id并更新到通行记录表中的时候获取锁异常",e);
		}finally {
			if (!getLock) {
				return;
			}
			lock.unlock();
			logger.info("正在将前12分钟的通行数据查询出学生id并更新到通行记录表中的时候释放锁");
		}
	}


}


